var free_space = '.';
var obstacle = '*';
var goal = 'A';

var scale=80;
var moves = 0;
var level = 1;
var goal_position;


//the level definitions
//each level is a string representing a 6x6 array of blocks
//
// . represents free space
// * represent obstacles
// A is the goal
// uppercase letters are vertical blocks
// lowercase letters are horizontal blocks

var levels=[
{levelstring:"........A.....A.....bbb.cccB.....B..", difficulty:7, min:5, moves:["bl2", "Bu3", "br3", "cr3", "Ad3"]},
{levelstring:"BbbbccB.A.....A..C.ddd.C....DCeee.D.", difficulty:8, min:8, moves:["Bd1", "bl1", "cl1", "Cu2", "Du3", "dr2", "er3", "Ad3"]},
{levelstring:"BbbbccB.AC....AC..dddC...eeeDEffggDE", difficulty:9, min:9, moves:["Bd1", "bl1", "Cu1", "Du3", "Eu3", "dr3", "er2", "gr1", "Ad3"]},
{levelstring:"**AbbbBCAcccBCddee.....Dfff..Dggg...", difficulty:11, min:9, moves:["fr2", "Bd2", "Cd2", "dl2", "el1", "Du1", "fr1", "gr3", "Ad4"]},
{levelstring:"..A.....Abbb.......ccB..*ddB..eeeB..", difficulty:21, min:7, moves:["cl1", "Ad2", "bl3", "Bu2", "dr2", "er3", "Ad2"]},
{levelstring:"bbAB.C..AB.C...BccDdd..ED.eeFEDfffF.", difficulty:22, min:8, moves:["Ad1", "br1", "Du3", "dl1", "el2", "Fu1", "fr2", "Ad3"]},
{levelstring:"BC.DbbBCAD....Acc.ddeeeE.fff.E.ggg.E", difficulty:23, min:9, moves:["Au1", "cl3", "Dd1", "bl1", "Eu3", "er1", "fr2", "gr2", "Ad4"]},
{levelstring:"..ABCD..ABCD.EbbccFEddGHFeeIGHfffIGH", difficulty:26, min:12, moves:["Eu2", "Fu3", "bl2", "dl2", "el1", "Ad3", "cl2", "Gu1", "Hu1", "Iu1", "fr3", "Ad1"]},
{levelstring:"**AbbB..AccB..ddC..eeeC..D.Eff.D.Egg", difficulty:26, min:16, moves:["Bd2", "br1", "cr1", "dl1", "el1", "Eu4", "fl2", "gl2", "Cd2", "dr2", "Bd2", "er3", "Du2", "fl2", "gl2", "Ad4"]},
{levelstring:"*B..*C.BAbbCccAD..dddD..EFeeffEF....", difficulty:31, min:13, moves:["Au1", "Cd2", "br1", "Du2", "cr3", "dr2", "Eu2", "Fu2", "el2", "fl1", "Cd2", "dr1", "Ad4"]},
{levelstring:"BCbbbDBCAE.DccAE.....EddFG...HFGeeeH", difficulty:32, min:14, moves:["Ad2", "Fu1", "Gu1", "el2", "Ed2", "cr4", "Bd1", "Cd1", "bl2", "Eu3", "dl1", "Hu1", "er3", "Ad1"]},
{levelstring:"*..*....AB....ABbb.ccddCeee.DCfff.D.", difficulty:38, min:14, moves:["Au1", "cl1", "Cd1", "dr1", "Bd2", "bl4", "Bu2", "dl2", "Du3", "dr1", "Cu2", "er3", "fr3", "Ad4"]},
{levelstring:"bbA**...A.B.cccCB....CB....Cdd.eee..", difficulty:38, min:12, moves:["Cu1", "dl4", "Bd2", "el1", "Cd2", "cr3", "Ad3", "cl3", "Cu1", "Bu1", "er3", "Ad1"]},
{levelstring:"*.AbbBC.AccBCdddDE.F.GDE.F.Gee*.....", difficulty:54, min:22, moves:["Cd2", "dl1", "Gu1", "el2", "Dd1", "Ed2", "Bd2", "br1", "cr1", "Gu2", "dr2", "Fu3", "dl2", "el1", "Gd3", "bl1", "cl1", "Bu2", "dr3", "Cu1", "el1", "Ad4"]},
{levelstring:"bbA.cc*.A.ddBeeeCDBEffCD.E.FCGgggF.G", difficulty:54, min:22, moves:["cl1", "dl1", "Du2", "Cd1", "er2", "Eu2", "fl1", "Fu1", "Gu1", "gr1", "Bd2", "fl1", "Ad3", "el1", "Dd1", "cr1", "br2", "Eu1", "el1", "Cu1", "gr2", "Ad1"]},
{levelstring:"*.A*B...A.BCbbccBC...DddEF.D.GEFeeeG", difficulty:60, min:22, moves:["Cu1", "Eu1", "Fu1", "el2", "Dd1", "dl2", "Bd3", "cr2", "br2", "Fu3", "bl2", "dl1", "Du1", "Gu1", "er1", "Ed1", "dl1", "Ad3", "cl2", "Bu1", "er2", "Ad1"]},
{levelstring:"BbbccCB...*C.DAddC.DAeeefffE.....Egg", difficulty:60, min:22, moves:["Bd1", "bl1", "Du1", "Au2", "el3", "Eu1", "gl1", "Cd3", "cr1", "dr1", "Eu3", "er2", "fr2", "Bd2", "Dd2", "dl4", "Ed1", "cl1", "Cu3", "er1", "fr1", "Ad4"]},
{levelstring:"*.A.*...ABbbcccBCD.EddCDFEeeCGFffggG", difficulty:60, min:22, moves:["Bu1", "Fu1", "fl1", "gl1", "Cd1", "cr2", "Eu3", "cl2", "dl1", "el1", "Bd3", "bl1", "Du2", "cr3", "Fu2", "dl1", "el1", "Ad3", "cl2", "Cu1", "gr1", "Ad1"]},
{levelstring:"*.Abbb..AB..cccB..CDddeeCDff.E*....E", difficulty:62, min:22, moves:["Dd1", "dl1", "el1", "Eu3", "er1", "fr2", "Bd3", "cr2", "dr1", "Du4", "cl2", "dl1", "Bu2", "fl3", "Bd2", "el1", "Ed2", "cr3", "Cu2", "dl1", "fl1", "Ad4"]},
{levelstring:"*.A*BC..A.BCbbccBC...DddEF.D..EFeee.", difficulty:62, min:22, moves:["Eu1", "Fu1", "el2", "Dd1", "dl2", "Bd3", "Cd3", "cr2", "br2", "Fu3", "bl2", "dl1", "Du1", "er1", "Ed1", "dl1", "Ad3", "cl2", "Bu1", "Cu1", "er2", "Ad1"]},
{levelstring:"*.AbbBC.AccBCdddDBee.ED..F.ED.*F.fff", difficulty:62, min:22, moves:["Bd2", "br1", "cr1", "er1", "Cd2", "dl1", "Eu3", "er1", "Fu1", "fl2", "Dd1", "Bd1", "dr3", "Cu2", "Fu3", "el2", "Ad3", "dl2", "Du1", "Bu1", "fr2", "Ad1"]},
{levelstring:"*.AbbbBCA.ccBCdddD.eeffD...EgghhhE..", difficulty:64, min:22, moves:["Cu1", "cl1", "Bd2", "dl2", "Du1", "fr1", "Eu2", "gl3", "Ed2", "fl1", "Dd2", "dr3", "Bu2", "el1", "gl1", "Ad3", "dl1", "Du2", "fr1", "Eu1", "hr3", "Ad1"]},
{levelstring:"*..B*.bbbB.C.DAccCEDA.ddEeeeF..fffF.", difficulty:64, min:22, moves:["Cu1", "cr1", "Eu1", "el1", "fl1", "Bd4", "cl1", "dl1", "Cd2", "br3", "Du2", "Au2", "cl2", "dl2", "Bu2", "Fu2", "er3", "fr3", "Ed2", "cl1", "dl1", "Ad4"]},
{levelstring:"bb.BccCddB*DCEeeeD.EAffF..A.GF.gggG.", difficulty:64, min:22, moves:["Cd3", "dl1", "Ed1", "el2", "Fd1", "fr1", "Bd3", "cl1", "Du1", "er3", "Au3", "el3", "Bu2", "fl2", "Gu1", "Fu1", "gr2", "Ed1", "fl2", "Bd2", "er3", "Ad4"]},
{levelstring:"*.A.bbBCAccDBCdddD.eeffD...EgghhhE..", difficulty:64, min:22, moves:["bl1", "Cu1", "Du1", "Bd2", "dl2", "fr1", "Eu2", "gl3", "Ed2", "fl1", "Dd3", "dr3", "Bu2", "el1", "gl1", "Ad3", "dl1", "Du3", "fr1", "Eu1", "hr3", "Ad1"]},
{levelstring:"*.Abbb*.ABccdddB..CDee.ECDff.Egg...E", difficulty:70, min:24, moves:["Eu1", "gr4", "Dd1", "el1", "Bd1", "cl1", "Eu1", "fr2", "Bd2", "dr2", "er1", "Du4", "dl2", "el1", "Bu2", "fl3", "gl4", "Bd2", "er2", "Ed2", "dr3", "Cu1", "fl1", "Ad4"]},
{levelstring:"*.A.*BC.AbbBCccc.Ddd.E.D.F.Eee.F.fff", difficulty:72, min:26, moves:["dr1", "Cd2", "cl1", "Eu1", "el1", "fl1", "Dd2", "Bd2", "br1", "Eu2", "cr2", "dr1", "Fu4", "cl2", "dl1", "el2", "Ed3", "bl1", "Bu2", "cr3", "Cu2", "dl1", "el1", "Du1", "fr1", "Ad4"]},
{levelstring:"*bb..B.ccddB..ACee.DACff*DggE..hhhE.", difficulty:72, min:24, moves:["cl1", "Du1", "gl1", "hl1", "Cd2", "el1", "fl1", "Bd4", "br3", "dr1", "Au2", "er1", "fr1", "Cu4", "el2", "fl2", "Eu2", "gr2", "Bu1", "hr3", "Dd2", "el2", "fl2", "Ad4"]},
{levelstring:".BAC.*.BAC.DbbbC.DEccdd.E.eeF.fff.F.", difficulty:76, min:22, moves:["Dd3", "dr1", "el1", "Cd3", "br1", "Eu3", "bl1", "cl1", "Cu3", "dl2", "el1", "Fu4", "dr2", "Cd3", "br3", "Ad3", "bl3", "Cu3", "dl1", "Du1", "fr3", "Ad1"]},
{levelstring:"bbb.....A.....AccBdddC.B...C.B...Cee", difficulty:89, min:9, moves:["br3", "Au1", "cl3", "Ad1", "bl3", "Bu2", "Cu3", "dr3", "Ad3"]},
{levelstring:"..AbbbccAB..C..BddCeeB..DEfff.DEgghh", difficulty:90, min:12, moves:["Ad1", "bl3", "Bu1", "er2", "Ad1", "cr1", "Cu1", "Du1", "Eu1", "fr1", "gl2", "Ad2"]},
{levelstring:"**AbbB..AccBdddC.BD..CeeDffgg.Dhhh..", difficulty:90, min:26, moves:["gr1", "Cd1", "dr1", "Du1", "hl1", "Cd1", "el3", "Cu1", "hr1", "Dd1", "dl1", "Cu1", "gl1", "Bd3", "br1", "cr1", "Cu2", "dr3", "Du2", "er2", "fl1", "Ad3", "dl1", "Bu1", "hr2", "Ad1"]},
{levelstring:"B*A*..B.AbbCBccc.Cddee.C...DffgggD..", difficulty:96, min:26, moves:["Cu1", "er2", "dr1", "Du1", "gr1", "Bd3", "cl1", "Du1", "fl3", "Dd1", "cr1", "Bu3", "dl1", "fl1", "gl1", "Dd1", "el1", "Cd3", "cr2", "Ad3", "cl1", "Cu3", "er1", "Du1", "gr3", "Ad1"]},
{levelstring:"......bbA...B.AC..BccCddee....ffgg..", difficulty:101, min:13, moves:["er3", "gr1", "fr1", "Bd2", "cl1", "Ad1", "br3", "Au1", "cr1", "Bu3", "cl1", "fl1", "Ad3"]},
{levelstring:"BCA.bbBCA*DEBCccDEddd.FEee..F*......", difficulty:105, min:17, moves:["bl1", "Eu1", "er2", "Fd1", "dr3", "Bd3", "Cd3", "cl2", "Ad1", "bl3", "Au1", "Du1", "cr3", "Bu2", "Cu2", "el2", "Ad4"]},
{levelstring:"........ABbb..AB.C..cccC.........ddd", difficulty:110, min:14, moves:["cl2", "dl3", "Bd3", "bl1", "Cu1", "cr3", "Ad1", "bl3", "Au1", "cl3", "Bu3", "cr3", "dr3", "Ad3"]},
{levelstring:".*A.*.bbA...Bccdd.Beeff.gg..C.hh..C.", difficulty:112, min:16, moves:["gr1", "hr1", "Bd2", "cl1", "el1", "Ad2", "br3", "Au2", "cr1", "er1", "Bu4", "cl1", "el1", "gl1", "hl1", "Ad4"]},
{levelstring:"**.B..bbbB.C.DA..C.DAccC.dddE..ee.E.", difficulty:114, min:18, moves:["Cu1", "cr1", "dl1", "Bd4", "cl1", "Cd2", "br3", "Du1", "Au1", "cl3", "Ad1", "bl1", "Cu1", "Bu2", "Eu2", "dr3", "el1", "Ad2"]},
{levelstring:"..ABbbccABC*DEddC.DE.eeeffgg.Fhhii.F", difficulty:116, min:22, moves:["el1", "Fu2", "gr2", "fr2", "Dd1", "Ed1", "dl2", "Ad1", "Bd1", "bl4", "Au1", "Bu1", "Cu1", "dr3", "Du1", "Eu1", "fl2", "gl1", "Fd2", "er1", "ir1", "Ad4"]},
{levelstring:"bbAB.*CDABccCDddeeffggE.hh..E*.ii...", difficulty:118, min:22, moves:["hr2", "Ed1", "gr2", "fr2", "Cd3", "ir1", "Dd3", "dl2", "fl2", "Ad2", "Bd2", "cl4", "Au2", "Bu2", "el2", "gl2", "Eu4", "er1", "gr1", "hr1", "ir1", "Ad4"]},
{levelstring:"*Bbbb..Bccc.ddAC..eeACffDggg.EDhhh.E", difficulty:120, min:22, moves:["br1", "cr1", "Au2", "dr1", "er1", "Du3", "el1", "gl1", "hl1", "Cd2", "dr2", "Ad2", "bl1", "cl1", "fl1", "Eu4", "dr1", "fr1", "Cu2", "gr3", "hr3", "Ad2"]},
{levelstring:"bbbB..*CABcc.CAddDee..EDFfffEDFgg.E.", difficulty:120, min:22, moves:["er1", "Fu2", "fl1", "Dd1", "dr1", "Bd3", "br3", "Cu1", "Au1", "dl3", "Bu1", "fr1", "Fd2", "dl1", "el1", "Ad2", "cl2", "Eu2", "Du2", "fr2", "gr2", "Ad2"]},
{levelstring:"*.AB*.bbAB...C.BccDCddEFDeeeEF.fff..", difficulty:120, min:22, moves:["Du1", "el1", "Ed1", "Fd1", "dr2", "Ad2", "fl1", "Bd3", "br4", "Cu2", "Au2", "cl3", "Bu3", "dl2", "Eu2", "Fu2", "er3", "fr3", "Dd2", "cl1", "dl2", "Ad4"]},
{levelstring:"..AB..bbAB..CDcc**CDddeeffgg..hhii..", difficulty:122, min:22, moves:["gr2", "fr2", "ir2", "hr2", "Cd2", "Dd2", "cl2", "dl2", "Ad2", "Bd2", "br4", "Au2", "Bu2", "cr2", "dr2", "Cu4", "Du4", "cl2", "dl2", "fl2", "hl2", "Ad4"]},
{levelstring:"bbb.*BCDcccBCDAEddeeAE.F.fff.F.gg.*.", difficulty:122, min:22, moves:["fl1", "Ed2", "dl1", "Fd1", "Bd2", "cr1", "Au1", "er3", "Cd1", "Dd1", "Ad1", "cl3", "Bu2", "dr1", "er1", "Eu4", "dl1", "el1", "Fu2", "fr3", "gl1", "Ad2"]},
{levelstring:"bbA.**.BAcc..Bddeeff.CDEF..CDEFggg.E", difficulty:122, min:22, moves:["fr1", "Fu1", "Dd1", "gl1", "Cd1", "fr2", "Bd2", "dl2", "Ad3", "br2", "dr2", "Fu3", "Bu3", "dl2", "el1", "Au2", "fl3", "Eu1", "Cu1", "Du1", "gr3", "Ad3"]},
{levelstring:"bbbB.C*.AB.C..ABccDE...FDEdddF.eee..", difficulty:124, min:22, moves:["Du1", "Eu1", "dl2", "el1", "Bd3", "cl1", "Cd1", "br3", "Au1", "Eu2", "cl2", "Bu2", "dr1", "Dd1", "cl1", "Ad1", "bl1", "Cu1", "Fu1", "dr2", "er3", "Ad3"]},
{levelstring:"bbA.*.BCA...BCccddeeeD.E...D.E.fff..", difficulty:124, min:22, moves:["Ed1", "fl1", "Dd1", "er3", "Bd2", "Cd2", "cl2", "Ad3", "br2", "cr2", "Bu3", "Cu3", "cl2", "dl1", "Au2", "el3", "Eu4", "dr1", "Du3", "er3", "fr3", "Ad3"]},
{levelstring:"*.Abb.ccA.BCDEddBCDE.FeefffF.G.ggg.G", difficulty:124, min:22, moves:["Cu1", "gl1", "Fd1", "el2", "Bd3", "dr1", "er1", "Ad2", "cr3", "Eu2", "Au2", "dl2", "el2", "Fu2", "Bu2", "Gu2", "fr3", "gr3", "Dd2", "dl1", "el1", "Ad4"]},
{levelstring:"bbA*..BCA.ccBCddeefff.DEgg..DE.hh..E", difficulty:126, min:22, moves:["cl1", "gr2", "Dd1", "fr2", "Bd2", "hr1", "Cd3", "dl2", "el1", "Eu3", "fr1", "Ad2", "cl3", "Au2", "el1", "fl2", "Du4", "er1", "fr2", "gr1", "hr1", "Ad4"]},
{levelstring:"bbA...B.AcccBddC*.eeeC.D.Eff.D.Egg..", difficulty:126, min:22, moves:["Du1", "fr2", "gr2", "Cd2", "er2", "Bd2", "dl1", "Ad1", "br3", "Au1", "dr2", "Bu3", "Eu4", "dl2", "el2", "Cu2", "fl4", "gl4", "Cd2", "Dd2", "er3", "Ad4"]},
{levelstring:"bbbB.C*DAB.C.DAccEF*..GEFdddG.....G.", difficulty:128, min:22, moves:["Fu1", "Ed1", "cr1", "dl1", "Bd3", "cl1", "Cd1", "br3", "Du1", "Au1", "cl2", "Bu1", "Gu2", "dr1", "Fd1", "cl1", "Ad1", "bl1", "Cu1", "Eu1", "dr2", "Ad3"]},
{levelstring:"bbbB.CcccB.C*DA.*E.DAddEF...G.FeeeG.", difficulty:128, min:22, moves:["Ed2", "dr1", "Fu1", "el1", "Bd4", "dl1", "Cd2", "cr3", "Du1", "Au1", "dl2", "Bu1", "Gu1", "er1", "Fd1", "dl1", "Ad1", "cl1", "Cu1", "Eu1", "er2", "Ad2"]},
{levelstring:"*..B.CbbbB.C*DA..E.DAccEF...G.FdddG.", difficulty:128, min:22, moves:["Ed2", "cr1", "Fu1", "dl1", "Bd4", "cl1", "Cd2", "br3", "Du1", "Au1", "cl2", "Bu1", "Gu1", "dr1", "Fd1", "cl1", "Ad1", "bl1", "Cu1", "Eu1", "dr2", "Ad2"]},
{levelstring:"*.....bbA*..BCAcccBCddDE...FDEee.FDE", difficulty:130, min:22, moves:["Au1", "Cd1", "cl2", "Du3", "Eu3", "dr2", "Fu1", "er4", "Bd2", "Cd1", "Fd1", "dl4", "Fu1", "el2", "Dd3", "Ed3", "cr2", "Ad3", "cl2", "Du1", "er1", "Ad1"]},
{levelstring:"B.AbbbB*A.C*B.ccCDdd.EFD.G.EF..Geee.", difficulty:137, min:25, moves:["cl1", "Eu2", "dr2", "Bd3", "cl1", "Dd1", "Gu1", "el1", "Fd1", "dr1", "Ad3", "bl3", "Eu1", "Cu1", "cr4", "Ed1", "br1", "Bu3", "Au2", "dl1", "Fu1", "er2", "Gd1", "dl2", "Ad3"]},
{levelstring:"B.bb*CBccc.CB.ADddeeAD.E.fff.E.ggg..", difficulty:140, min:26, moves:["bl1", "fl1", "Ed1", "gl1", "Dd2", "dl1", "Cd2", "cr2", "Au1", "er3", "Ad1", "cl1", "Cu2", "dr1", "er1", "Du2", "fr1", "Bd2", "cl2", "Du2", "dl1", "el1", "Eu2", "fr2", "gr3", "Ad2"]},
{levelstring:"B.A.bbB.AccCBddeeC..ffD.gggED..*.Ehh", difficulty:143, min:27, moves:["Cd2", "cr1", "er1", "fl1", "Eu3", "gr1", "Bd3", "dl1", "hl2", "Dd1", "Cd1", "fr3", "Ad2", "bl4", "Ed1", "cl4", "Au2", "Eu2", "el2", "fl2", "Du4", "er1", "fr1", "Cu2", "gr2", "hr1", "Ad4"]},
{levelstring:".BAbbb*BAccCdd.D.C...Dee*ff.E.gghhE.", difficulty:150, min:26, moves:["Dd1", "dr3", "Bd2", "Ad2", "bl3", "cl2", "Cu1", "dr1", "Du3", "dl1", "el1", "Cd4", "dr1", "er1", "Dd3", "br3", "cr3", "Bu2", "Au2", "dl4", "Du2", "el4", "Eu2", "fr2", "hr1", "Ad4"]},
{levelstring:"**AbbbccA..BCddd.BC.ee.BC..DffgggD..", difficulty:152, min:26, moves:["el1", "Du1", "gr1", "Cd1", "dl1", "Du1", "fl3", "Dd1", "Bd2", "dr3", "Cu1", "gl1", "Dd1", "er2", "Ad2", "bl1", "cr1", "Cu1", "fl1", "Ad1", "dl1", "Bu3", "er1", "Du1", "gr3", "Ad1"]},
{levelstring:"*.AbbbccA.ddBeee.CB*ff.CB..DgghhhD..", difficulty:164, min:28, moves:["dl1", "Cu1", "fr2", "Du1", "hr1", "Bd1", "el1", "Du1", "gl3", "Dd1", "er1", "Bu1", "hl1", "Dd1", "fl1", "Cd2", "er2", "Ad2", "cr1", "Bu1", "gl1", "Ad1", "el1", "Cu2", "fr1", "Du1", "hr3", "Ad1"]},
{levelstring:"Bbbb..Bcc..*B.Add*eeA.C.fff.C.ggg...", difficulty:284, min:18, moves:["br2", "cr2", "Au1", "fr1", "Cd1", "er3", "Ad1", "gr1", "Bd3", "cl3", "Au2", "dl3", "el1", "Cu3", "er1", "fr2", "gr2", "Ad4"]},
{levelstring:".BbbbC.Bcc.CddAeeCffADggEhhD**Eiii..", difficulty:290, min:22, moves:["cr1", "Au1", "fr1", "Eu1", "il1", "Dd1", "gl1", "Cd1", "br1", "Au1", "dr1", "Eu3", "dl1", "Ad1", "bl1", "Cu1", "fl1", "gr1", "hl1", "Du1", "ir3", "Ad3"]},
{levelstring:".BbbbC.Bcc.CddAD*CeeADffEgghh.Eiii..", difficulty:291, min:23, moves:["cr1", "Au1", "er1", "Eu1", "hr1", "il1", "Dd2", "fl1", "Cd1", "br1", "Au1", "dr1", "Eu3", "dl1", "Ad1", "bl1", "Cu1", "el1", "fr1", "gl1", "Du1", "ir3", "Ad3"]},
{levelstring:"bbb..B*Ccc.B.CADddeeADE*FfffE.F...E.", difficulty:294, min:22, moves:["cr1", "Au1", "er1", "Fu2", "fl1", "Dd1", "dl1", "Bd1", "br3", "Cu1", "Au1", "dl2", "Du1", "fr1", "Fd2", "dl1", "el1", "Ad2", "cl1", "Eu2", "fr2", "Ad2"]},
{levelstring:".Bbbcc.BddeeffA.*CD.AggCDhhE..iiiE..", difficulty:296, min:22, moves:["Cd2", "gr1", "Eu2", "hr2", "Ad1", "fr1", "Du3", "fl1", "Au1", "hl3", "Ad1", "Ed2", "fr2", "Bd2", "dl1", "el1", "gl1", "Cu3", "gr1", "Eu1", "ir3", "Ad1"]},
{levelstring:".*.B*CDbbB.CDccddEeeA..E.FA.ff.Fgghh", difficulty:296, min:22, moves:["Du1", "cl1", "fl1", "Ed1", "dr1", "Bd2", "br2", "Au3", "cr1", "er1", "Dd4", "cl1", "el1", "Ad2", "bl3", "Au1", "Bu1", "er3", "Du1", "Fu1", "gl2", "Ad3"]},
{levelstring:".Bbbb..BccddeeA.*CD.AffCDggE..hhhE..", difficulty:296, min:22, moves:["Cd2", "fr1", "Eu2", "gr2", "Ad1", "er1", "Du3", "el1", "Au1", "gl3", "Ad1", "Ed2", "er2", "Bd2", "cl1", "dl1", "fl1", "Cu3", "fr1", "Eu1", "hr3", "Ad1"]},
{levelstring:"B.ACbbB.ACDEB.ccDEddeeFE.GffF*.G.gg*", difficulty:296, min:24, moves:["cl1", "Cd1", "bl1", "Eu1", "gl1", "Fd1", "er2", "dr2", "Bd3", "cl1", "Ad1", "bl3", "Au1", "Cu1", "Du1", "cr3", "Ad1", "br1", "Bu3", "Gu3", "dl2", "fl2", "gl2", "Ad3"]},
{levelstring:".Bbb*..BccddeeA.*CD.AffCDggE..hhhE..", difficulty:296, min:22, moves:["Cd2", "fr1", "Eu2", "gr2", "Ad1", "er1", "Du3", "el1", "Au1", "gl3", "Ad1", "Ed2", "er2", "Bd2", "cl1", "dl1", "fl1", "Cu3", "fr1", "Eu1", "hr3", "Ad1"]},
{levelstring:"BCAbb*BCAD.*BccDE...ddE.....FGeeffFG", difficulty:298, min:24, moves:["Eu1", "dl1", "Fu1", "Gu1", "fr2", "Dd3", "cr1", "dr1", "Cd3", "er1", "Bd3", "cl2", "Ad1", "bl3", "Au1", "Eu1", "cr3", "Ad1", "br1", "Bu3", "Cu2", "dl2", "el1", "Ad3"]},
{levelstring:"B.ACbbB.AC.DBccc.Dddee.Eff...Eggg...", difficulty:310, min:26, moves:["fr1", "Ed1", "er2", "dr1", "gr1", "Bd3", "cl1", "Cd3", "bl1", "Du1", "cr3", "Ad1", "bl3", "Au1", "cl3", "Cu3", "cr3", "Ad1", "br1", "Bu3", "dl1", "el1", "fl1", "Eu1", "gr2", "Ad3"]},
{levelstring:"*.A..BbbAccBC..DddC..D..CeeeE.ffggE.", difficulty:312, min:26, moves:["Ad2", "br1", "Cu1", "el1", "Dd1", "dl1", "Bd3", "cr1", "dr1", "Du3", "er1", "Eu1", "gr1", "fr1", "Cd2", "bl1", "Au2", "dl4", "Eu1", "Bu1", "er2", "Ad3", "dr1", "Cu1", "fl1", "Ad1"]},
{levelstring:"BbbC*.B.ACccB.AddDee..ED.fffEDgg...*", difficulty:312, min:26, moves:["er1", "Bd1", "bl1", "Au1", "dl2", "fl1", "Cd4", "cl1", "Du2", "Ed1", "er3", "Cu2", "fr1", "gr1", "Bd2", "dl1", "Ad2", "cl3", "Au1", "Cu1", "el2", "Eu3", "er1", "fr2", "gr2", "Ad3"]},
{levelstring:"B..C*DBbbC.DB.AccDddA.E..eeeE..fff..", difficulty:314, min:26, moves:["Dd3", "cr1", "el1", "Ed1", "fl1", "Cd4", "br2", "Au2", "cl3", "Du3", "dr4", "Cu2", "er1", "fr1", "Bd3", "cl1", "Ad2", "bl3", "Au1", "Cu1", "dl2", "Eu3", "dr1", "er2", "fr2", "Ad3"]},
{levelstring:"*bbB.CcccB.CD.AddCD.A.E.DeeeE.ffgg..", difficulty:314, min:26, moves:["Cd3", "dr1", "Bd2", "br2", "cr3", "Du1", "Au2", "el1", "Bd1", "dl3", "Bu1", "Eu1", "er1", "gr1", "fr1", "Dd2", "dl1", "Ad2", "cl1", "Cu2", "er2", "Ad1", "dr1", "Du1", "fl1", "Ad1"]},
{levelstring:"bbb..BccA..B.CA.dd.CeeD.fffED.*..Egg", difficulty:315, min:25, moves:["dl1", "Bd1", "br3", "Au1", "dl1", "Du2", "er2", "Eu1", "gl3", "Ed1", "el2", "Dd3", "dr1", "er1", "Ad2", "cr3", "Cu2", "Au2", "dl3", "el3", "Eu2", "Du2", "fr3", "gr2", "Ad4"]},
{levelstring:"B.AbbCBDA.ECBDccEC..ddF.ee.GF..*.G*.", difficulty:318, min:26, moves:["Du1", "cl1", "Cd1", "br1", "dl1", "Gu4", "cr1", "dr1", "er2", "Dd3", "Bd3", "cl2", "Ad1", "Gd1", "bl4", "Au1", "Gu1", "Eu1", "cr3", "Ad1", "br1", "Bu3", "Du2", "dl2", "el2", "Ad3"]},
{levelstring:"bbbB.CD..B.CD.Acc.D.Addd.eeeE.ffggE*", difficulty:318, min:26, moves:["Au1", "cr1", "Bd1", "br1", "Du1", "dl3", "el1", "Bd2", "cl1", "Cd1", "br2", "Au1", "cl2", "Bu2", "Eu3", "dr3", "er3", "gr1", "fr1", "Dd3", "cl1", "Ad3", "cr1", "Du1", "fl1", "Ad1"]},
{levelstring:"BbbC..BDACcc.DAddEeee..E*....F.ff.*F", difficulty:333, min:27, moves:["Bd1", "bl1", "Au1", "er2", "fr1", "Dd3", "dl2", "el2", "Cd3", "dr2", "Ad1", "br4", "Bu1", "Au1", "dl2", "Cu3", "dr1", "er2", "Du4", "dl2", "el2", "fl2", "Cd4", "cl1", "Eu1", "er3", "Ad4"]},
{levelstring:".BbbCD.BA.CDccA.E.F.ddE.F..GeeF*.G*.", difficulty:683, min:27, moves:["Dd1", "dl1", "Gu2", "el2", "Ed1", "Cd1", "br2", "Au1", "Gu2", "cr2", "dr1", "Bd3", "cl2", "Ad1", "Gd1", "bl4", "Au1", "Gu1", "Cu1", "cr3", "Ad1", "br1", "Fu3", "Bu2", "dl2", "el2", "Ad3"]},
{levelstring:"BbbC.DBccC.DB.AddD..A.E.eeffE.......", difficulty:686, min:26, moves:["Bd1", "bl1", "Dd3", "dr1", "Cd2", "cr3", "Au2", "Cu2", "dl2", "Eu1", "fr1", "er1", "Bd2", "dl2", "Ad2", "Cd2", "cl4", "Au2", "Cu2", "Eu2", "dr3", "Ad2", "cr1", "Bu2", "el1", "Ad2"]},
{levelstring:"B..CbbBccC..Bddd...*Aee.ffA.D*gghhD.", difficulty:710, min:30, moves:["dr2", "Au1", "fr1", "Bd2", "cl1", "Au2", "dl2", "el1", "Du3", "er2", "hr2", "gr1", "Bd1", "dl1", "Cd4", "el2", "Dd2", "dr3", "Ad1", "bl4", "Au1", "dl3", "Du3", "er2", "Cu4", "dr3", "Bu1", "fr2", "gl1", "Ad4"]},
{levelstring:"bbA..BC*A*.BCcc..DCddeeDffggE.....E.", difficulty:1352, min:26, moves:["cr2", "Ad1", "br3", "Cu1", "Au1", "cl1", "dl1", "el1", "Eu3", "er1", "dr1", "gr1", "fr1", "Cd3", "cl2", "Ad1", "bl3", "Au1", "Eu1", "cr3", "Ad1", "br1", "Cu3", "dl1", "fl1", "Ad3"]},
{levelstring:"B..CbbBccC.DBddd.D.*AeeDffA.E.ggg.E.", difficulty:2529, min:39, moves:["Dd2", "dr2", "Au1", "fr1", "gr1", "Bd3", "cl1", "Au2", "dl3", "Cd1", "bl1", "Du3", "er1", "Cd2", "dr1", "Bu1", "gl1", "Cd1", "el2", "Dd3", "dr2", "Ad1", "bl3", "Au1", "dl2", "Eu4", "dr2", "er1", "Ad2", "cr1", "Bu1", "fl1", "Ad1", "dl1", "Du3", "er1", "Cu1", "gr3", "Ad1"]},

//junk levels:
//{levelstring:"BCAbb*BCAD.*BccDE...ddEF....GFeeffGF", difficulty:298, min:24, moves:["Eu1", "dl1", "Fu1", "Gu1", "fr2", "Dd3", "cr1", "dr1", "Cd3", "er1", "Bd3", "cl2", "Ad1", "bl3", "Au1", "Eu1", "cr3", "Ad1", "br1", "Bu3", "Cu2", "dl2", "el1", "Ad3"]},
//{levelstring:".B.*...BbbccddA.*CD.AeeCDffE..gggE..", difficulty:296, min:22, moves:["Cd2", "er1", "Eu2", "fr2", "Ad1", "dr1", "Du3", "dl1", "Au1", "fl3", "Ad1", "Ed2", "dr2", "Bd2", "bl1", "cl1", "el1", "Cu3", "er1", "Eu1", "gr3", "Ad1"]},
//{levelstring:"bbbB.C*DAB*C.DAccEF...GEFdddG.......", difficulty:128, min:22, moves:["Fu1", "Ed1", "cr1", "dl1", "Bd3", "cl1", "Cd1", "br3", "Du1", "Au1", "cl2", "Bu1", "Gu1", "dr1", "Fd1", "cl1", "Ad1", "bl1", "Cu1", "Eu1", "dr2", "Ad3"]},
//{levelstring:"bb.BccdddB.C*DA.*C.DAeeEF...GEFfffG.", difficulty:128, min:22, moves:["Fu1", "Ed1", "er1", "fl1", "Bd4", "el1", "Cd1", "dr3", "Du1", "Au1", "el2", "Bu1", "Gu1", "fr1", "Fd1", "el1", "Ad1", "dl1", "Cu1", "Eu1", "fr2", "Ad2"]},
//{levelstring:"bb.B.CcccB.C*DA.*E.DAddEF...G.FeeeG.", difficulty:128, min:22, moves:["Ed2", "dr1", "Fu1", "el1", "Bd4", "dl1", "Cd2", "cr3", "Du1", "Au1", "dl2", "Bu1", "Gu1", "er1", "Fd1", "dl1", "Ad1", "cl1", "Cu1", "Eu1", "er2", "Ad2"]},
//{levelstring:"..ABbbccABC*DEddC.DE.eeeffgg.F.hh..F", difficulty:116, min:22, moves:["el1", "Fu2", "gr2", "fr2", "Dd1", "Ed1", "dl2", "Ad1", "Bd1", "bl4", "Au1", "Bu1", "Cu1", "dr3", "Du1", "Eu1", "fl2", "gl1", "Fd2", "er1", "hl1", "Ad4"]},
//{levelstring:"B*AbbbB*A...Bccc.Cddee.C...DffgggD..", difficulty:96, min:26, moves:["Cu1", "er2", "dr1", "Du1", "gr1", "Bd3", "cl1", "Du1", "fl3", "Dd1", "cr1", "Bu3", "dl1", "fl1", "gl1", "Dd1", "el1", "Cd2", "cr2", "Ad3", "cl1", "Cu2", "er1", "Du1", "gr3", "Ad1"]},
//{levelstring:"bbAccB.*AddBeeeC.BD..CffDgghh.Diii..", difficulty:90, min:26, moves:["hr1", "Cd1", "er1", "Du1", "il1", "Cd1", "fl3", "Cu1", "ir1", "Dd1", "el1", "Cu1", "hl1", "Bd3", "cr1", "dr1", "Cu2", "er3", "Du2", "fr2", "gl1", "Ad3", "el1", "Bu1", "ir2", "Ad1"]},
//{levelstring:"........A.....A.....................", difficulty:1, min:1, moves:["Ad3"]},
];

//IE doesn't have this function so we add it(IE is junk but people still use it for some reason)
if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

function levelpage()
{
    var c = $(".container");
    c.html('');
    var levels_on_row = Math.ceil(Math.sqrt(levels.length));
    var w = (c.width()*0.9)/levels_on_row;
    for (var i=0; i < levels.length; i++)
    {
        var cls = 'level_choice';
        if (levels[i].solved)
        {
            cls += ' level_solved';
        }
        else if (levels[i].locked)
            cls += ' level_locked';
        else
        {
            cls += ' level_unsolved';
        }
        var onclick = 'javascript:loadLevel('+(i+1)+');';
        var left = w * (i % levels_on_row) * 1.1;
        var top = w * Math.floor(i / levels_on_row) * 1.1;
        if (levels[i].locked)
        {
            c.append($("<div class='"+cls+"' style='top:"+top+"px; left:"+left+"px; width:"+w+"px; height:"+w+"px;'>" + (i+1) + "</div>"));
        }
        else
        {
            c.append($("<a class='"+cls+"' style='top:"+top+"px; left:"+left+"px; width:"+w+"px; height:"+w+"px;' href='"+onclick+"'>" + (i+1) + "</a>"));
        }
    }
    $('.level_choice').each(
        function(index)
        {
            if ($(this).hasClass('level_locked'))
            $(this).attr('title','Locked, solve '+lockedCondition(index)+' levels to unlock')
        });
    $('.level_solved').attr('title','Solved');
    $('.level_unsolved').attr('title','Not Solved');
}

function lockedCondition(i)
{
    return Math.floor(i*2/3);
}

//initialize the game
function init()
{
    var maj = $(".major_container");
    var w = maj.width();
    scale = w/8;
    var score_height = scale;
    maj.append($("<div class='container' style='width:"+(scale*8)+"px;height:"+(scale*8)+"px;'/>"));
    var c = $(".container");
    
    var solved_before = 0;
    //try to get the levels allready played from cookies
    for (var i=0; i < levels.length; i++)
    {
        var cookieLevel = readCookie(levels[i].levelstring);
        if (cookieLevel)
        {
            levels[i].solved = parseInt(cookieLevel);
            if (levels[i].solved)
                solved_before++;
        }
        if (solved_before < lockedCondition(i))
        {
            levels[i].locked = true;
        }
    }
    //load the first unplayed level
    for (var i=0; i < levels.length; i++)
    {
        if (!levels[i].solved)
        {
            level = i+1;
            break;
        }
    }

    loadLevel(level);
      
    $("#level").text(level);
}

function loadLevel(lv)
{
	if (levels[lv-1])
	{
	    fromString(levels[lv-1].levelstring);
	    level = lv;
	    moves = 0;
	    updateTexts();
  	}
  	else
  	{
  			$(".container").html('<div style="text-align:center;background-color:White;height:100%;padding-top:50px;">' +
'<b>Stay in touch</b><br /><br />' +
'<a style="vertical-align: middle;" href="http://feeds.feedburner.com/gamescripter" rel="alternate" title="Subscribe to my feed" type="application/rss+xml"><img alt="" style="border: 0pt none ; width: 96px;" src="http://2.bp.blogspot.com/_dFvILwVn1B4/Sx18MXDRWDI/AAAAAAAAABc/W0TfWNcvCnA/s320/subscribe.png"/></a>' +
'<br /><b>More levels are on the way.</b></div>');
		if (level <= 0) level = 0;
		if (level >= levels.length) level = levels.length+1;
  	}
}


//creates the DOM elements representing the level and binds events to them
//takes a levelstring as input
function fromString(string)
{
    var i,j;
    goal_position = -1;
    $(".container").html("");
    
    //build the border around the level
    var string2= "";
    for (i = 0; i < 8; i++)
        for (j = 0; j < 8; j++)
        {
            if (i==0 || i==7 || j==0 || j==7)
            {
                if (j == goal_position)
                    string2 += free_space;
                else
                    string2 += obstacle;
            }
            else
            {
                string2 += string.charAt((i-1)*6+(j-1));
                if (string.charAt((i-1)*6+(j-1)) == goal)
                    goal_position = j;
            }
        }
    var lvl = string2.split('');
    //start interpreting blocks
    for (i = 0; i < 8; i++)
    {
        for (j = 0; j < 8; j++)
        {
            var index = i*8 + j;
            var left = j*scale;
            var top = i*scale;
            var width = scale-1;
            var height = scale-1;
            var cls = 'block';
            var block = lvl[index];
            
            //vertical block
            if (block >= 'B' && block <= 'Z')
            {
                var long_block = (lvl[index+16] == block);
                height = scale * (long_block?3:2);
                lvl[index+8] = free_space;
                if (long_block)
                    lvl[index+16] = free_space;
                cls += " vblock";
            }
            //horizontal block
            else if (block >= 'a' && block <= 'z')
            {
                var long_block = (lvl[index+2] == block);
                width = scale * (long_block?3:2);
                lvl[index+1] = free_space;
                if (long_block)
                    lvl[index+2] = free_space;
                cls += " hblock";
            }
            else if (block == obstacle)
            {
                cls += " border";
            }
            else if (block == goal)
            {
                //small goal block
                height = scale * 2;
                lvl[index+8] = free_space;
                cls += " vblock goal";
                goal_position = j;
            }
            else
            {
                continue;
            }
            
            var div_block = $(".container").append($("<div class='"+cls+"' style='top:"+top+"px;left:"+left+"px;height:"+height+"px;width:"+width+"px;position:absolute;'></div>"));
        }
    }
    
    //make them draggable
    
    $('.block').draggable(
    {
    		containment: 'parent',
    		addClasses: false,
        //record the starting position
        start: function(ev, ui)
        {
            ev.target.oldTop = $(this).position().top;
            ev.target.oldLeft = $(this).position().left;
        },
        //snap to grid and check if the block has actually moved
        stop: function(ev, ui)
        {
            //snap to grid
            $(this).css(
            {
                top: function (index, value)
                {
                    return Math.round(parseFloat(value)/scale)*scale;
                },
                left: function (index, value)
                {
                    return Math.round(parseFloat(value)/scale)*scale;
                }
            });
            if ($(this).position().top != ev.target.oldTop || $(this).position().left != ev.target.oldLeft)
            {
                contain();
                moves++;
                updateTexts();
                //if this was the goal block, verify if the level is complete
                if ($(this).hasClass('goal'))
                    verifyGoal();
            }
        },
        iframeFix: true
    });
    $('.vblock').draggable('option', 'axis', 'y');//only on the y axis
    $('.hblock').draggable('option', 'axis', 'x');//only on the x axis
    $('.border').draggable( "destroy" );
    //set the limits of the draggable blocks
    contain();
}

function updateTexts()
{
    $("#moves").text('' + moves + '(' + levels[level-1].moves.length + ((levels[level-1].solved)?') - Solved':')'));
    $("#level").text(level);
    if (levels[level] && levels[level].locked)
    {
        $("#load_next").hide();
    }
    else
    {
        $("#load_next").show();
    }
}

//applies draggable limits to each type of block
//works on the DOM elements allready in place
function contain()
{
    //for each vertical block, verify the siblings position and update the draggable containment
    $('.vblock').each( function(i, domElem)
    {
        var b = $(domElem);
        var p = b.position();
        p.right = p.right || p.left + b.width();
        p.bottom = p.bottom || p.top + b.height();
        var ct = 0;
        var cb = b.parent().height();
        
        var sibs = b.siblings();
        sibs.each(function(j, sibElem)
        {
            var s = $(sibElem);
            var sp = s.position();
            sp.right = sp.right || sp.left + s.width();
            sp.bottom = sp.bottom || sp.top + s.height();
            if (b != s)
            {
                if (p.top >= sp.bottom && p.left >= sp.left && p.right <= sp.right)
                    if (ct < sp.bottom) ct = sp.bottom;
                if (Math.round(p.bottom) <= Math.round(sp.top) && p.left >= sp.left && p.right <= sp.right)
                    if (cb > sp.top) cb = sp.top;
            }
        });
        b.draggable("option", "containment", [p.left, ct + b.parent().offset().top, p.right, cb + b.parent().offset().top - b.height()]);
    });
    
    //for each horizontal block, verify the siblings position and update the draggable containment
    $('.hblock').each( function(i, domElem)
    {
        var b = $(domElem);
        var p = b.position();
        p.right = p.right || p.left + b.width();
        p.bottom = p.bottom || p.top + b.height();
        var cl = 0;
        var cr = b.parent().width();
        
        var sibs = b.siblings();
        sibs.each(function(j, sibElem)
        {
            var s = $(sibElem);
            var sp = s.position();
            sp.right = sp.right || sp.left + s.width();
            sp.bottom = sp.bottom || sp.top + s.height();
            if (b != s)
            {
                if (p.left >= sp.right && p.top >= sp.top && p.bottom <= sp.bottom)
                    if (cl < sp.right) cl = sp.right;
                if (p.right <= sp.left && p.top >= sp.top && p.bottom <= sp.bottom)
                    if (cr > sp.left) cr = sp.left;
            }
        });
        b.draggable("option", "containment", [cl + b.parent().offset().left, p.top, cr + b.parent().offset().left  - b.width(), p.bottom]);
    });
    
    //allow the goal block to be dragged outside of the field if no siblings are blocking it
    var c = $('.goal').draggable("option", "containment");
    var g = $('.goal');
    if (c[3] == g.parent().height() + g.parent().offset().top - g.height())
    {
        c[3] += g.height()/2;
        g.draggable("option", "containment", c);
    }
}

//verify if the level is complete
function verifyGoal()
{
    var g = $(".goal");
    if (g.position().top + g.height() >= g.parent().height() - scale )
    {
        var cookieLevel = readCookie(levels[level-1].levelstring);
        levels[level-1].solved = moves;
        createCookie(levels[level-1].levelstring,moves,365);
        
        var solved_before = 0;
        //try to get the levels allready played from cookies
        for (var i=0; i < levels.length; i++)
        {
            if (levels[i].solved)
            {
                solved_before++;
            }
            if (solved_before < lockedCondition(i))
            {
                levels[i].locked = true;
            }
            else
            {
                levels[i].locked = false;
            }
        }
        
        loadLevel(++level);
        updateTexts();
        return false;
    }
}

function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}